From aa970bcfa33cf9e88647e8268c4a18f7670c8d75 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Ludger=20Kr=C3=A4mer?= <dbluelle@onlinehome.de>
Date: Mon, 17 Sep 2018 18:57:48 +0200
Subject: [PATCH] make llvm dependency optional (disabled by default)

---
 CMakeLists.txt                      | 82 ++++++++++++++++-------------
 README                              |  5 +-
 src/main.cpp                        |  5 +-
 src/scripting/abc.cpp               |  6 +++
 src/scripting/abc.h                 | 21 ++++++--
 src/scripting/abc_codesynt.cpp      |  3 ++
 src/scripting/toplevel/toplevel.cpp |  2 +
 7 files changed, 82 insertions(+), 42 deletions(-)

diff --git a/CMakeLists.txt b/CMakeLists.txt
index b76e228fe..6fc6d174e 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -194,6 +194,7 @@ SET(ENABLE_CURL TRUE CACHE BOOL "Enable CURL? (Required for Downloader functiona
 SET(ENABLE_GLES2 FALSE CACHE BOOL "Build with OpenGLES 2.0 support instead of OpenGL")
 SET(ENABLE_LIBAVCODEC TRUE CACHE BOOL "Enable libavcodec and dependent functionality?")
 SET(ENABLE_RTMP TRUE CACHE BOOL "Enable librtmp and dependent functionality?")
+SET(ENABLE_LLVM FALSE CACHE BOOL "Enable support for llvm based jit execution (currently broken)")
 SET(ENABLE_PROFILING FALSE CACHE BOOL "Enable profiling support? (Causes performance issues)")
 SET(ENABLE_MEMORY_USAGE_PROFILING FALSE CACHE BOOL "Enable profiling of memory usage? (Causes performance issues)")
 SET(PLUGIN_DIRECTORY "${LIBDIR}/mozilla/plugins" CACHE STRING "Directory to install Firefox plugin to")
@@ -217,40 +218,45 @@ SET(CMAKE_INSTALL_RPATH "${PRIVATELIBDIR}")
 # Libraries we need
 INCLUDE(FindPkgConfig REQUIRED)
 INCLUDE(FindGettext REQUIRED)
-INCLUDE(FindLLVM REQUIRED)
-IF(${LLVM_STRING_VERSION} VERSION_LESS 2.8)
-	MESSAGE(FATAL_ERROR "LLVM >=2.8 is required!")
-ENDIF(${LLVM_STRING_VERSION} VERSION_LESS 2.8)
-IF(${LLVM_STRING_VERSION} VERSION_EQUAL 2.9)
-	MESSAGE(FATAL_ERROR "LLVM !=2.9 is required!")
-ENDIF(${LLVM_STRING_VERSION} VERSION_EQUAL 2.9)
-IF(${LLVM_STRING_VERSION} VERSION_EQUAL 2.8)
-	ADD_DEFINITIONS(-DLLVM_28)
-ENDIF(${LLVM_STRING_VERSION} VERSION_EQUAL 2.8)
-IF(${LLVM_STRING_VERSION} VERSION_EQUAL 3.0)
-	ADD_DEFINITIONS(-DLLVM_30)
-ENDIF(${LLVM_STRING_VERSION} VERSION_EQUAL 3.0)
-IF(${LLVM_STRING_VERSION} VERSION_GREATER 3.0)
-	ADD_DEFINITIONS(-DLLVM_31)
-ENDIF(${LLVM_STRING_VERSION} VERSION_GREATER 3.0)
-IF(${LLVM_STRING_VERSION} VERSION_GREATER 3.3)
-	ADD_DEFINITIONS(-DLLVM_34)
-ENDIF(${LLVM_STRING_VERSION} VERSION_GREATER 3.3)
-IF(${LLVM_STRING_VERSION} VERSION_GREATER 3.4)
-	ADD_DEFINITIONS(-DLLVM_35)
-ENDIF(${LLVM_STRING_VERSION} VERSION_GREATER 3.4)
-IF(NOT (${LLVM_STRING_VERSION} VERSION_LESS 3.6))
-	ADD_DEFINITIONS(-DLLVM_36)
-ENDIF(NOT (${LLVM_STRING_VERSION} VERSION_LESS 3.6))
-IF(NOT ${LLVM_STRING_VERSION} VERSION_LESS 3.7)
-	ADD_DEFINITIONS(-DLLVM_37)
-ENDIF(NOT ${LLVM_STRING_VERSION} VERSION_LESS 3.7)
-IF(NOT ${LLVM_STRING_VERSION} VERSION_LESS 3.8)
-	ADD_DEFINITIONS(-DLLVM_38)
-ENDIF(NOT ${LLVM_STRING_VERSION} VERSION_LESS 3.8)
-IF(NOT ${LLVM_STRING_VERSION} VERSION_LESS 5.0)
-	ADD_DEFINITIONS(-DLLVM_50)
-ENDIF(NOT ${LLVM_STRING_VERSION} VERSION_LESS 5.0)
+
+IF (ENABLE_LLVM)
+	ADD_DEFINITIONS(-DLLVM_ENABLED)
+	INCLUDE(FindLLVM REQUIRED)
+	IF(${LLVM_STRING_VERSION} VERSION_LESS 2.8)
+		MESSAGE(FATAL_ERROR "LLVM >=2.8 is required!")
+	ENDIF(${LLVM_STRING_VERSION} VERSION_LESS 2.8)
+	IF(${LLVM_STRING_VERSION} VERSION_EQUAL 2.9)
+		MESSAGE(FATAL_ERROR "LLVM !=2.9 is required!")
+	ENDIF(${LLVM_STRING_VERSION} VERSION_EQUAL 2.9)
+	IF(${LLVM_STRING_VERSION} VERSION_EQUAL 2.8)
+		ADD_DEFINITIONS(-DLLVM_28)
+	ENDIF(${LLVM_STRING_VERSION} VERSION_EQUAL 2.8)
+	IF(${LLVM_STRING_VERSION} VERSION_EQUAL 3.0)
+		ADD_DEFINITIONS(-DLLVM_30)
+	ENDIF(${LLVM_STRING_VERSION} VERSION_EQUAL 3.0)
+	IF(${LLVM_STRING_VERSION} VERSION_GREATER 3.0)
+		ADD_DEFINITIONS(-DLLVM_31)
+	ENDIF(${LLVM_STRING_VERSION} VERSION_GREATER 3.0)
+	IF(${LLVM_STRING_VERSION} VERSION_GREATER 3.3)
+		ADD_DEFINITIONS(-DLLVM_34)
+	ENDIF(${LLVM_STRING_VERSION} VERSION_GREATER 3.3)
+	IF(${LLVM_STRING_VERSION} VERSION_GREATER 3.4)
+		ADD_DEFINITIONS(-DLLVM_35)
+	ENDIF(${LLVM_STRING_VERSION} VERSION_GREATER 3.4)
+	IF(NOT (${LLVM_STRING_VERSION} VERSION_LESS 3.6))
+		ADD_DEFINITIONS(-DLLVM_36)
+	ENDIF(NOT (${LLVM_STRING_VERSION} VERSION_LESS 3.6))
+	IF(NOT ${LLVM_STRING_VERSION} VERSION_LESS 3.7)
+		ADD_DEFINITIONS(-DLLVM_37)
+	ENDIF(NOT ${LLVM_STRING_VERSION} VERSION_LESS 3.7)
+	IF(NOT ${LLVM_STRING_VERSION} VERSION_LESS 3.8)
+		ADD_DEFINITIONS(-DLLVM_38)
+	ENDIF(NOT ${LLVM_STRING_VERSION} VERSION_LESS 3.8)
+	IF(NOT ${LLVM_STRING_VERSION} VERSION_LESS 5.0)
+		ADD_DEFINITIONS(-DLLVM_50)
+	ENDIF(NOT ${LLVM_STRING_VERSION} VERSION_LESS 5.0)
+ENDIF(ENABLE_LLVM)
+
 INCLUDE(FindZLIB REQUIRED)
 INCLUDE(FindFreetype REQUIRED)
 IF(NOT(ENABLE_GLES2))
@@ -405,7 +411,9 @@ IF(GTHREAD_FOUND AND (GTHREAD_VERSION VERSION_LESS 2.32.0))
   ADD_DEFINITIONS(-DHAVE_G_THREAD_INIT)
 ENDIF(GTHREAD_FOUND AND (GTHREAD_VERSION VERSION_LESS 2.32.0))
 
-INCLUDE_DIRECTORIES(${LLVM_INCLUDE_DIR})
+IF (ENABLE_LLVM)
+    INCLUDE_DIRECTORIES(${LLVM_INCLUDE_DIR})
+ENDIF(ENABLE_LLVM)
 INCLUDE_DIRECTORIES(${ZLIB_INCLUDE_DIR})
 INCLUDE_DIRECTORIES(${FREETYPE_INCLUDE_DIRS})
 IF(ENABLE_GLES2)
@@ -445,7 +453,9 @@ IF(CMAKE_CXX_COMPILER_ID STREQUAL "Clang")
   SET(CMAKE_SHARED_LINKER_FLAGS_RELEASE "-s")
 ENDIF(CMAKE_CXX_COMPILER_ID STREQUAL "Clang")
 
-LINK_DIRECTORIES(${LLVM_LIB_DIR})
+IF(ENABLE_LLVM)
+    LINK_DIRECTORIES(${LLVM_LIB_DIR})
+ENDIF(ENABLE_LLVM)
 
 IF(ENABLE_CURL)
   pkg_check_modules(CURL REQUIRED libcurl)
diff --git a/README b/README
index 231d54b7b..0d693e98d 100644
--- a/README
+++ b/README
@@ -10,10 +10,13 @@ INSTALLATION
 ============
 
 To compile this software you need to install development packages for
-llvm (version 2.8 or >= 3.0), opengl, curl, zlib, libavcodec, libavresample
+opengl, curl, zlib, libavcodec, libavresample
 libglew, pcre, librtmp, cairo, libboost-filesystem, 
 sdl2, sdl2_mixer, libjpeg, libavformat, pango, liblzma
 
+If jit compilation using llvm is enabled(disabled by default),
+you also need the development packages for llvm (version 2.8 or >= 3.0)
+
 If compiling the PPAPI (Chromium) plugin is enabled (on by default), keep in mind that 
 it will replace the adobe flash plugin, as only one flash plugin is allowed in chromium. 
 
diff --git a/src/main.cpp b/src/main.cpp
index cb3c7573b..4de0e748e 100644
--- a/src/main.cpp
+++ b/src/main.cpp
@@ -342,7 +342,10 @@ int main(int argc, char* argv[])
 	if(fileName==NULL)
 	{
 		LOG(LOG_ERROR, "Usage: " << argv[0] << " [--url|-u http://loader.url/file.swf]" <<
-			" [--disable-interpreter|-ni] [--enable-fast-interpreter|-fi] [--enable-jit|-j]" <<
+			" [--disable-interpreter|-ni] [--enable-fast-interpreter|-fi]" <<
+#ifdef LLVM_ENABLED
+			" [--enable-jit|-j]" <<
+#endif
 			" [--log-level|-l 0-4] [--parameters-file|-p params-file] [--security-sandbox|-s sandbox]" <<
 			" [--exit-on-error] [--HTTP-cookies cookie] [--air] [--avmplus] [--disable-rendering]" <<
 #ifdef PROFILING_SUPPORT
diff --git a/src/scripting/abc.cpp b/src/scripting/abc.cpp
index c99f89d6e..9e8d36fdc 100644
--- a/src/scripting/abc.cpp
+++ b/src/scripting/abc.cpp
@@ -23,6 +23,7 @@
 
 #include "compat.h"
 
+#ifdef LLVM_ENABLED
 #include <llvm/ExecutionEngine/ExecutionEngine.h>
 #ifndef LLVM_36
 #include <llvm/ExecutionEngine/JIT.h>
@@ -60,6 +61,7 @@
 #ifdef HAVE_TRANSFORMS_SCALAR_GVN_H
 #  include <llvm/Transforms/Scalar/GVN.h>
 #endif
+#endif
 #include "logger.h"
 #include "swftypes.h"
 #include <sstream>
@@ -1940,6 +1942,7 @@ void ABCVm::Run(ABCVm* th)
 #endif
 	if(th->m_sys->useJit)
 	{
+#ifdef LLVM_ENABLED
 #ifdef LLVM_31
 		llvm::TargetOptions Opts;
 #ifndef LLVM_34
@@ -2006,6 +2009,7 @@ void ABCVm::Run(ABCVm* th)
 		th->FPM->add(llvm::createDeadStoreEliminationPass());
 
 		th->registerFunctions();
+#endif
 	}
 	th->registerClasses();
 
@@ -2052,11 +2056,13 @@ void ABCVm::Run(ABCVm* th)
 		snapshotCount++;
 #endif
 	}
+#ifdef LLVM_ENABLED
 	if(th->m_sys->useJit)
 	{
 		th->ex->clearAllGlobalMappings();
 		delete th->module;
 	}
+#endif
 #ifndef NDEBUG
 	inStartupOrClose= true;
 #endif
diff --git a/src/scripting/abc.h b/src/scripting/abc.h
index 63bf51b05..467eccb5f 100644
--- a/src/scripting/abc.h
+++ b/src/scripting/abc.h
@@ -34,6 +34,7 @@
 #include "scripting/flash/system/flashsystem.h"
 #include "scripting/toplevel/toplevel.h"
 
+#ifdef LLVM_ENABLED
 namespace llvm {
 	class ExecutionEngine;
 #ifdef LLVM_36
@@ -50,9 +51,12 @@ namespace legacy {
 	class Value;
 	class LLVMContext;
 }
+#endif // LLVM_ENABLED
 
 namespace lightspark
 {
+
+#ifdef LLVM_ENABLED
 struct block_info;
 #ifdef LLVM_28
 typedef const llvm::Type* LLVMTYPE;
@@ -60,8 +64,6 @@ typedef const llvm::Type* LLVMTYPE;
 typedef llvm::Type* LLVMTYPE;
 #endif
 
-bool isVmThread();
-
 std::ostream& operator<<(std::ostream& o, const block_info& b);
 
 typedef std::pair<llvm::Value*, STACK_TYPE> stack_entry;
@@ -69,6 +71,9 @@ inline stack_entry make_stack_entry(llvm::Value* v, STACK_TYPE t)
 {
 	return std::make_pair(v, t);
 }
+#endif
+
+bool isVmThread();
 
 class method_info
 {
@@ -78,6 +83,7 @@ friend class SyntheticFunction;
 private:
 	struct method_info_simple info;
 
+#ifdef LLVM_ENABLED
 	typedef std::vector<std::pair<int, STACK_TYPE> > static_stack_types_vector;
 	//Helper function to sync only part of the static stack to the memory
 	void consumeStackForRTMultiname(static_stack_types_vector& stack, int multinameIndex) const;
@@ -92,7 +98,7 @@ friend class SyntheticFunction;
 	struct BuilderWrapper;
 	//Does analysis on function code to find optimization chances
 	void doAnalysis(std::map<unsigned int,block_info>& blocks, BuilderWrapper& builderWrapper);
-
+#endif
 public:
 #ifdef PROFILING_SUPPORT
 	std::map<method_info*,uint64_t> profCalls;
@@ -104,7 +110,9 @@ friend class SyntheticFunction;
 	SyntheticFunction::synt_function f;
 	ABCContext* context;
 	method_body_info* body;
+#ifdef LLVM_ENABLED
 	SyntheticFunction::synt_function synt_method(SystemState* sys);
+#endif
 	bool needsArgs() { return info.needsArgs(); }
 	bool needsActivation() { return info.needsActivation(); }
 	bool needsRest() { return info.needsRest(); }
@@ -121,7 +129,9 @@ friend class SyntheticFunction;
 	const Type* returnType;
 	bool hasExplicitTypes;
 	method_info():
+#ifdef LLVM_ENABLED
 		llvmf(NULL),
+#endif
 #ifdef PROFILING_SUPPORT
 		profTime(0),
 		validProfName(false),
@@ -469,6 +479,7 @@ friend class asAtom;
 	static void constructFunction(asAtom & ret, call_context* th, asAtom& f, asAtom* args, int argslen);
 	void parseRPCMessage(_R<ByteArray> message, _NR<ASObject> client, _NR<Responder> responder);
 
+#ifdef LLVM_ENABLED
 	//Opcode tables
 	void register_table(LLVMTYPE ret_type,typed_opcode_handler* table, int table_len);
 	static opcode_handler opcode_table_args_pointer_2int[];
@@ -479,7 +490,7 @@ friend class asAtom;
 	static typed_opcode_handler opcode_table_void[];
 	static typed_opcode_handler opcode_table_voidptr[];
 	static typed_opcode_handler opcode_table_bool_t[];
-
+#endif
 
 	//Synchronization
 	Mutex event_queue_mutex;
@@ -873,6 +884,7 @@ friend class asAtom;
 
 	MemoryAccount* vmDataMemory;
 
+#ifdef LLVM_ENABLED
 	llvm::ExecutionEngine* ex;
 	llvm::Module* module;
 
@@ -882,6 +894,7 @@ friend class asAtom;
 	llvm::FunctionPassManager* FPM;
 #endif
 	llvm::LLVMContext& llvm_context();
+#endif
 
 	ABCVm(SystemState* s, MemoryAccount* m) DLL_PUBLIC;
 	/**
diff --git a/src/scripting/abc_codesynt.cpp b/src/scripting/abc_codesynt.cpp
index 5b71b289e..6ee977b3e 100644
--- a/src/scripting/abc_codesynt.cpp
+++ b/src/scripting/abc_codesynt.cpp
@@ -17,6 +17,8 @@
     along with this program.  If not, see <http://www.gnu.org/licenses/>.
 **************************************************************************/
 
+#ifdef LLVM_ENABLED
+
 #ifdef LLVM_28
 #define alignof alignOf
 #define LLVMMAKEARRAYREF(T) T
@@ -4783,3 +4785,4 @@ void ABCVm::wrong_exec_pos()
 {
 	assert_and_throw(false && "wrong_exec_pos");
 }
+#endif //LLVM_ENABLED
diff --git a/src/scripting/toplevel/toplevel.cpp b/src/scripting/toplevel/toplevel.cpp
index 55ee6028f..c2c5bce10 100644
--- a/src/scripting/toplevel/toplevel.cpp
+++ b/src/scripting/toplevel/toplevel.cpp
@@ -345,6 +345,7 @@ void SyntheticFunction::call(asAtom& ret, asAtom& obj, asAtom *args, uint32_t nu
 		ABCVm::optimizeFunction(this);
 	}
 
+#ifdef LLVM_ENABLED
 	//Temporarily disable JITting
 	if(getSystemState()->useJit && mi->body->exceptions.size()==0 && ((hit_count>=jit_hit_threshold && codeStatus==method_body_info::OPTIMIZED) || getSystemState()->useInterpreter==false))
 	{
@@ -352,6 +353,7 @@ void SyntheticFunction::call(asAtom& ret, asAtom& obj, asAtom *args, uint32_t nu
 		val=mi->synt_method(getSystemState());
 		assert(val);
 	}
+#endif
 	++mi->body->hit_count;
 
 	//Prepare arguments
